<template>
  <div style="display: flex">
    <el-select v-model="state.mainValue" @change="handleSelectChange">
      <el-option v-for="option in state.mainOptions" :value="option.value" :label="option.label" />
    </el-select>
    <el-select v-model="state.minorValue" :disabled="!state.mainValue" :loading="loading" style="margin-left: 10px">
      <el-option v-for="option in state.minorOptions" :value="option.value" :label="option.label" />
    </el-select>
  </div>
  <slot :html="html" />
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";

import { ElSelect, ElOption } from "element-plus";

interface OptionType {
  value: string;
  label: string;
}

const html = ref(`
<template>
  <div style="display: flex">
    <el-select v-model="state.mainValue" @change="handleSelectChange">
      <el-option v-for="option in state.mainOptions" :value="option.value" :label="option.label" />
    </el-select>
    <el-select v-model="state.minorValue" :disabled="!state.mainValue" :loading="loading" style="margin-left: 10px">
      <el-option v-for="option in state.minorOptions" :value="option.value" :label="option.label" />
    </el-select>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";

import { ElSelect, ElOption } from "element-plus";

interface OptionType {
  value: string;
  label: string;
}

const loading = ref(false);

const state = reactive<{
  mainValue: string;
  mainOptions: OptionType[];
  minorValue: string;
  minorOptions: OptionType[];
}>({
  mainValue: "",
  mainOptions: [],
  minorValue: "",
  minorOptions: []
});

// 获取主键下拉选项
const queryMainOptions: () => Promise<OptionType[]> = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve([
        { value: "1", label: "选项一" },
        { value: "2", label: "选项二" }
      ]);
    }, 500);
  });
};

// 获取联动下拉选项
const queryMinorOptions: () => Promise<OptionType[]> = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(state.mainValue);
      switch (state.mainValue) {
        case "1":
          resolve([
            { value: "3", label: "选项三" },
            { value: "4", label: "选项四" }
          ]);
          break;
        case "2":
          resolve([
            { value: "5", label: "选项五" },
            { value: "6", label: "选项六" }
          ]);
          break;
        default:
          break;
      }
    }, 2000);
  });
};

// 主键下拉框变动
const handleSelectChange = async () => {
  state.minorValue = "";
  loading.value = true;
  await queryMinorOptions().then(options => (state.minorOptions = options));
  loading.value = false;
};

onMounted(() => queryMainOptions().then(options => (state.mainOptions = options)));
<\/script>
`);

const loading = ref(false);

const state = reactive<{
  mainValue: string;
  mainOptions: OptionType[];
  minorValue: string;
  minorOptions: OptionType[];
}>({
  mainValue: "",
  mainOptions: [],
  minorValue: "",
  minorOptions: []
});

// 获取主键下拉选项
const queryMainOptions: () => Promise<OptionType[]> = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve([
        { value: "1", label: "选项一" },
        { value: "2", label: "选项二" }
      ]);
    }, 500);
  });
};

// 获取联动下拉选项
const queryMinorOptions: () => Promise<OptionType[]> = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(state.mainValue);
      switch (state.mainValue) {
        case "1":
          resolve([
            { value: "3", label: "选项三" },
            { value: "4", label: "选项四" }
          ]);
          break;
        case "2":
          resolve([
            { value: "5", label: "选项五" },
            { value: "6", label: "选项六" }
          ]);
          break;
        default:
          break;
      }
    }, 2000);
  });
};

// 主键下拉框变动
const handleSelectChange = async () => {
  state.minorValue = "";
  loading.value = true;
  await queryMinorOptions().then(options => (state.minorOptions = options));
  loading.value = false;
};

onMounted(() => queryMainOptions().then(options => (state.mainOptions = options)));
</script>
